#include "ByteMatrix.h"
#include <sstream>

namespace newcode {
using namespace std;
using namespace zxing;

ByteMatrix::ByteMatrix(int x, int y)
{
    this->x = x;
    this->y = y;
    data = vector<vector<unsigned char> >(y);
    for (int i = 0; i < y; i++)
    {
        data[i] = vector<unsigned char>(x);
    }
}

unsigned char& ByteMatrix::operator()(int x, int y)
{
    return data[y][x];
}

int ByteMatrix::getX() const
{
    return x;
}

int ByteMatrix::getY() const
{
    return y;
}

unsigned char* ByteMatrix::getRow(int index) const
{
    return const_cast<unsigned char*>(&data[index][0]);
}

void ByteMatrix::setRow(unsigned char* bytes, int index)
{
    data[index].assign(bytes, bytes + x);
}

ByteMatrix::operator string() const
{
    ostringstream oss;
    for (int i = 0; i < y; i++)
    {
        for (int j = 0; j < x; j++)
        {
            int luminance = data[i][j];
            char c;
            if (luminance < 0x40)
            {
                c = '#';
            }
            else if (luminance < 0x80)
            {
                c = '+';
            }
            else if (luminance < 0xC0)
            {
                c = '.';
            }
            else
            {
                c = ' ';
            }
            oss << c;
        }
        oss << "\n";
    }

    return oss.str();
}

ostream& operator<<(ostream &out, const ByteMatrix &bm)
{
    for (int y = 0; y < bm.y; y++)
    {
        for (int x = 0; x < bm.x; x++)
        {
            if (bm.data[y][x] <= 0xF)
            {
                out << " " << hex << (int)bm.data[y][x] << " ";
            }
            else
            {
                out << hex << (int)bm.data[y][x] << " ";
            }
        }
        out << "\n";
    }
    return out;
}

}
